/* eslint-disable prefer-const */
import axios, { AxiosInstance } from "axios";

// 创建 axios 实例
const instance: AxiosInstance = axios.create({
    baseURL: '/api',
    timeout: 3000,
});

// 用于防止重复刷新token
let isRefreshing = false;
let refreshPromise: Promise<string> | null = null;

// 刷新token的函数
const refreshToken = async (): Promise<string> => {
    try {
        console.log('Calling refresh token API...');
        const refreshTokenValue = localStorage.getItem('refreshToken');
        if (!refreshTokenValue) {
            throw new Error('No refresh token found');
        }

        const response = await instance.post('/refreshToken', {
            refreshToken: refreshTokenValue
        });

        console.log('Refresh token response:', response.data);

        const { token, refreshToken: newRefreshToken } = response.data;

        // 更新本地存储的token
        localStorage.setItem('token', token);
        localStorage.setItem('refreshToken', newRefreshToken);

        return token;
    } catch (error) {
        console.error('Refresh token failed:', error);
        // 刷新失败，清除本地token
        localStorage.removeItem('token');
        localStorage.removeItem('refreshToken');
        throw error;
    }
};

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    let token = localStorage.getItem('token');
    if (token) {
        try {
            // 如果 token 是 JSON 字符串，需要解析
            const parsedToken = JSON.parse(token);
            config.headers.Authorization = `Bearer ${parsedToken}`;
        } catch {
            config.headers.Authorization = `Bearer ${token}`;
        }
    }
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
}, async function (error) {
    console.log('Response error:', error.response?.status, error.response?.data);

    const originalRequest = error.config;

    // 如果是 401 错误且没有重试过
    if (error.response?.status === 401 && !originalRequest._retry) {
        console.log('401 error detected, attempting token refresh...');
        originalRequest._retry = true;

        // 如果正在刷新，等待刷新完成
        if (isRefreshing) {
            console.log('Token refresh already in progress, waiting...');
            try {
                const newToken = await refreshPromise;
                originalRequest.headers.Authorization = `Bearer ${newToken}`;
                return instance(originalRequest);
            } catch (refreshError) {
                console.error('Wait for refresh failed:', refreshError);
                return Promise.reject(refreshError);
            }
        }

        // 开始刷新 token
        console.log('Starting token refresh...');
        isRefreshing = true;
        refreshPromise = refreshToken();

        try {
            const newToken = await refreshPromise;
            console.log('Token refresh successful, retrying original request...');
            originalRequest.headers.Authorization = `Bearer ${newToken}`;
            return instance(originalRequest);
        } catch (refreshError) {
            console.error('Token refresh failed:', refreshError);
            return Promise.reject(refreshError);
        } finally {
            isRefreshing = false;
            refreshPromise = null;
        }
    }

    // 其他错误处理
    switch (error.response?.status) {
        case 400:
            console.log('请求错误');
            break;
        case 401:
            console.log('未授权 - token可能已过期');
            // 401错误时清除本地token并跳转登录页
            localStorage.removeItem('token');
            localStorage.removeItem('refreshToken');
            window.location.href = '/login';
            break;
        case 403:
            console.log('拒绝访问');
            break;
        case 404:
            console.log('资源未找到');
            break;
        case 500:
            console.log('服务器端出错');
            break;
        default:
            console.log('其他错误:', error.response?.status);
            break;
    }
    return Promise.reject(error);
});

export default instance;